package com.zhixing.user.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.DriverLicenseOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.DriverLicenseOCRResponse;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRResponse;
import com.zhixing.common.exception.ZhixingException;
import com.zhixing.user.domain.enums.Sex;
import com.zhixing.user.domain.vo.DriverLicenseOcrVO;
import com.zhixing.user.domain.vo.IdCardOcrVO;
import com.zhixing.user.service.CloudService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

import static com.zhixing.common.domain.enums.HttpStatus.FILE_UPLOAD_FAIL;

@Service
public class CloudServiceImpl implements CloudService {

    @Value("${tencent.secretId}")
    private String secretId;
    @Value("${tencent.secretKey}")
    private String secretKey;
    @Value("${tencent.region}")
    private String region;
    @Value("${tencent.bucketName}")
    private String bucketName;

    @Override
    public String upload(MultipartFile file, String path) {
        // 建立客户端
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        clientConfig.setHttpProtocol(HttpProtocol.https);
        COSClient cosClient = new COSClient(cred, clientConfig);

        // 上传图片
        String fileType = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf("."));
        String key = path + "/" + IdUtil.fastSimpleUUID() + fileType;
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(file.getSize());
        PutObjectRequest putObjectRequest;
        try {
            putObjectRequest = new PutObjectRequest(bucketName, key, file.getInputStream(), objectMetadata);
        } catch (IOException e) {
            throw new ZhixingException(FILE_UPLOAD_FAIL);
        }
        cosClient.putObject(putObjectRequest);

        // 获取图片url
        URL url = cosClient.getObjectUrl(bucketName, key);
        cosClient.shutdown();
        return url.toString();
    }

    private OcrClient getOcrClient() {
        Credential cred = new Credential(secretId, secretKey);
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ocr.tencentcloudapi.com");
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        return new OcrClient(cred, region, clientProfile);
    }

    @Override
    public IdCardOcrVO idCardOcr(MultipartFile file) {
        // 身份证识别
        OcrClient client = getOcrClient();
        IDCardOCRRequest req = new IDCardOCRRequest();

        // 上传图片
        String idCardUrl = upload(file, "idCard");
        req.setImageUrl(idCardUrl);
        IDCardOCRResponse resp;
        try {
            resp = client.IDCardOCR(req);
        } catch (TencentCloudSDKException e) {
            throw new ZhixingException(FILE_UPLOAD_FAIL);
        }

        // 获取识别结果
        IdCardOcrVO idCardOcrVO;
        if (StrUtil.isNotEmpty(resp.getName())) {
            // 身份证正面
            idCardOcrVO = IdCardOcrVO.builder().name(resp.getName())
                    .sex(StrUtil.equals(resp.getSex(), "男") ? Sex.MALE : Sex.FEMALE)
                    .birthDate(LocalDate.parse(resp.getBirth(), DateTimeFormatter.ofPattern("yyyy/M/d")))
                    .idNumber(resp.getIdNum()).address(resp.getAddress())
                    .idCardFrontUrl(idCardUrl).build();
        }
        else {
            // 身份证反面
            idCardOcrVO = IdCardOcrVO.builder()
                    .idCardExpireDate(LocalDate.parse(resp.getValidDate().split("-")[1], DateTimeFormatter.ofPattern("yyyy.MM.dd")))
                    .idCardBackUrl(idCardUrl).build();
        }
        return idCardOcrVO;
    }

    @Override
    public DriverLicenseOcrVO driverLicenseOcr(MultipartFile file) {
        // 驾驶证识别
        OcrClient client = getOcrClient();
        DriverLicenseOCRRequest req = new DriverLicenseOCRRequest();

        // 上传图片
        String driverLicenseUrl = upload(file, "driverLicense");
        req.setImageUrl(driverLicenseUrl);
        DriverLicenseOCRResponse resp;
        try {
            resp = client.DriverLicenseOCR(req);
        } catch (TencentCloudSDKException e) {
            throw new ZhixingException(FILE_UPLOAD_FAIL);
        }

        // 获取识别结果
        if (StrUtil.isEmpty(resp.getClass_())) throw new ZhixingException(FILE_UPLOAD_FAIL);
        return new DriverLicenseOcrVO(resp.getName(), resp.getCardCode(), resp.getClass_(),
                LocalDate.parse(resp.getDateOfFirstIssue(), DateTimeFormatter.ofPattern("yyyy-MM-dd")),
                LocalDate.parse(resp.getEndDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), driverLicenseUrl);
    }
}
